/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package TestPrincipal;

import analisis.InterproceduralKInfiniteAnalysis;
import java.util.HashSet;
import java.util.Set;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import reticulado.AbstractNode;
import reticulado.PointsToGraph;
import soot.Body;
import soot.Local;
import static org.junit.Assert.*;

/**
 *
 * @author Santiago Avendaño
 */
public class TestEj4 {

    private static final String campoF1 = "f1";
    private static final String campoF2 = "f2";
    private static Local variablex;
    private static Local variabley;
    private static Local variablew;
    private static Local variablez;

    public TestEj4() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    @Test
    public void Test1() {
        System.out.println("TEST1");
        InterproceduralKInfiniteAnalysis inter = new InterproceduralKInfiniteAnalysis("CasosTestInter.Test1", "test_1");
        PointsToGraph res = inter.getResult();
        System.out.println("Resultado del analisis interprocedural (Ej 4)");
        System.out.println(res);
        setearVariables(inter.getMetodoPrincipal().getActiveBody());
        assertFalse("z.f1 may-alias z.f2 ? NO", res.mayAlias(variablez, campoF1, variablez, campoF2));
        assertTrue("z.f2 may-alias z ? SI", res.mayAlias(variablez, campoF2, variablez));
    }

    @Test
    public void Test2() {
        System.out.println("TEST2");
        InterproceduralKInfiniteAnalysis inter = new InterproceduralKInfiniteAnalysis("CasosTestInter.Test2", "test_02");
        PointsToGraph res = inter.getResult();
        System.out.println("Resultado del analisis interprocedural");
        System.out.println(res);
        setearVariables(inter.getMetodoPrincipal().getActiveBody());
        assertTrue("z.f2 may-alias z.f1 ? SI", res.mayAlias(variablez, campoF1, variablez, campoF2));
        assertFalse("z.f2 may-alias z ? NO", res.mayAlias(variablez, campoF2, variablez));
    }

    @Test
    public void Test3() {
        System.out.println("TEST3");
        InterproceduralKInfiniteAnalysis inter = new InterproceduralKInfiniteAnalysis("CasosTestInter.Test3", "test_03");
        PointsToGraph res = inter.getResult();
        System.out.println("Resultado del analisis interprocedural");
        System.out.println(res);
        setearVariables(inter.getMetodoPrincipal().getActiveBody());
        Set<AbstractNode> alcanzadoszf1 = res.alcanzados(variablez, campoF1);
        Set<AbstractNode> alcanzadoszf1f1 = new HashSet<AbstractNode>();
        Set<AbstractNode> alcanzadoszf1f2 = new HashSet<AbstractNode>();
        for (AbstractNode nodo : alcanzadoszf1) {
            alcanzadoszf1f1.addAll(res.alcanzados(nodo, campoF1));
            alcanzadoszf1f2.addAll(res.alcanzados(nodo, campoF2));
        }
        assertTrue("z.f1.f1 maybe null ? NO", res.analizarNulidad(alcanzadoszf1f1) == PointsToGraph.RespuestaNulidad.NO_ES_NULL);
    }

    @Test
    public void Test5() {
        System.out.println("TEST5");
        InterproceduralKInfiniteAnalysis inter = new InterproceduralKInfiniteAnalysis("CasosTestInter.Test5", "test_05");
        PointsToGraph res = inter.getResult();
        System.out.println("Resultado del analisis interprocedural");
        System.out.println(res);
        setearVariables(inter.getMetodoPrincipal().getActiveBody());
        assertFalse("x may-alias w --> SÍ para ej3, NO para ej4", res.mayAlias(variablex, variablew));
    }

    private void setearVariables(Body b) {
        for (Local v : b.getLocals()) {
            if (v.getName().equals("x")) {
                variablex = v;
            }
            if (v.getName().equals("y")) {
                variabley = v;
            }
            if (v.getName().equals("w")) {
                variablew = v;
            }
            if (v.getName().equals("z")) {
                variablez = v;
            }
        }
    }
}
